在這之前需要講到 Communicating sequential processes
CSP 理論是描述獨立併發的實體通過共享的通訊進行通信,Golang 藉由 CSP模型的一些概念來實現併發理論的支持
不要以共享內存的方式進行通信,相反的 要通過通信來共享內存
Do not communicate by sharing memory; instead, share memory by communicating.
使用共享數據的方式進行通信,衍生出要考慮資源競爭及上鎖問題。也影響程式碼的複雜度
所以這章節我們要討論的是 channel
var variable_name chan variale_type
使用 make 初始化並設定緩存空間為3
可以使用 chan<- 寫入值
可以使用 <-chan 取出通道原先存放的值
package main
import (
"fmt"
)
func main() {
var intChan chan int
//緩衝容量為3
intChan = make(chan int, 3)
fmt.Printf("int chan=%v p=%p\n", intChan, &intChan)
//寫入值
intChan <- 10
num := 211
intChan <- num
fmt.Printf("len = %d cap = %d\n", len(intChan), cap(intChan))
fmt.Printf("從通道中取出原先放入的值 %d\n", <-intChan)
fmt.Printf("從通道中取出原先放入的值 %d\n", <-intChan)
}
當 channl 使用 close func 關閉之後就無法再進行寫入,只能讀取
package main
import (
"fmt"
)
func main() {
var intChan chan int
//緩衝容量為3
intChan = make(chan int, 3)
fmt.Printf("int chan=%v p=%p\n", intChan, &intChan)
//寫入值
intChan <- 10
num := 211
intChan <- num
fmt.Printf("len = %d cap = %d\n", len(intChan), cap(intChan))
fmt.Printf("從通道中取出原先放入的值 %d\n", <-intChan)
//關閉後就無法再繼續寫入,只能將通道的參數取出
close(intChan)
fmt.Printf("從通道中取出原先放入的值 %d\n", <-intChan)
}
package main
import "fmt"
func main() {
intChan := make(chan int, 100)
for i := 0; i < 100; i++ {
intChan <- i
}
close(intChan)
for v := range intChan {
fmt.Println(v)
}
}
package main
import (
"fmt"
"time"
)
func write(c chan<- int) {
for i := 1; i <= 100; i++ {
c <- i * 2
time.Sleep(100 * time.Millisecond)
}
close(c)
}
func main() {
i := make(chan int, 10)
go write(i)
for v := range i {
fmt.Println(v)
}
}
當 chan 設定只有一個緩存空間,可以達到同步的效果
package main
import (
"fmt"
"time"
)
func write(c chan<- int) {
time.Sleep(3 * time.Second)
c <- 10
close(c)
}
func main() {
i := make(chan int, 1)
go write(i)
fmt.Println(<-i)
}
用五分鐘了解什麼是 unbuffered vs buffered channel
使用 Go Channel 及 Goroutine 時機
Golang CSP并发模型
Concurrency in Go
Go的CSP並發模型